<!doctype html>
<html>
	<head>
		<meta charset="utf-8">
		<title>Missing Data</title>
		<meta name="viewport" content="width=device-width, initial-scale=1">

		<link rel="stylesheet" href="../dist/uPlot.min.css">
	</head>
	<body>
		<script src="../dist/uPlot.iife.js"></script>

		<script>
			let data = [
				[1566453600,1566453660,1566453720,1566453780,1566453840,1566453900,1566453960,1566454020,1566454080,1566454140,1566454200,1566454260,1566454320,1566454380,1566454440,1566454500,1566454560,1566454620,1566454680,1566454740,1566454800,1566454860,1566454920,1566454980,1566455040,1566455100,1566455160,1566455220,1566455280,1566455340,1566455400,1566455460,1566455520,1566455580,1566455640,1566455700,1566455760,1566455820,1566455880,1566455940,1566456000,1566456060,1566456120,1566456180,1566456240,1566456300,1566456360,1566456420,1566456480,1566456540,1566456600,1566456660,1566456720,1566456780,1566456840,1566456900,1566456960,1566457020,1566457080,1566457140,1566457200,1566457260,1566457320,1566457380,1566457440,1566457500,1566457560,1566457620,1566457680,1566457740,1566457800,1566457860,1566457920,1566457980,1566458040,1566458100,1566458160,1566458220,1566458280,1566458340,1566458400,1566458460,1566458520,1566458580,1566458640,1566458700,1566458760,1566458820,1566458880,1566458940,1566459000,1566459060,1566459120,1566459180,1566459240,1566459300,1566459360,1566459420,1566459480,1566459540,1566459600,1566459660,1566459720,1566459780,1566459840,1566459900,1566459960,1566460020,1566460080,1566460140,1566460200,1566460260,1566460320,1566460380,1566460440,1566460500,1566460560,1566460620,1566460680,1566460740,1566460800,1566460860,1566460920,1566460980,1566461040,1566461100,1566461160,1566461220,1566461280,1566461340,1566461400,1566461460,1566461520,1566461580,1566461640,1566461700,1566461760,1566461820,1566461880,1566461940,1566462000,1566462060,1566462120,1566462180,1566462240,1566462300,1566462360,1566462420,1566462480,1566462540,1566462600,1566462660,1566462720,1566462780,1566462840,1566462900,1566462960,1566463020,1566463080,1566463140,1566463200,1566463260,1566463320,1566463380,1566463440,1566463500,1566463560,1566463620,1566463680,1566463740,1566463800,1566463860,1566463920,1566463980,1566464040,1566464100,1566464160,1566464220,1566464280,1566464340,1566464400,1566464460,1566464520,1566464580,1566464640,1566464700,1566464760,1566464820,1566464880,1566464940,1566465000,1566465060,1566465120,1566465180,1566465240,1566465300,1566465360,1566465420,1566465480,1566465540],
				[0.54,0.15,0.16,0.15,0.19,0.26,0.32,0.15,0.15,0.28,0.29,0.33,0.18,0.17,0.17,0.33,0.32,0.23,0.15,0.15,0.24,0.29,0.16,0.17,0.17,0.45,0.28,0.16,0.17,0.17,0.24,0.3,0.19,0.19,0.17,0.24,0.29,0.22,0.18,0.28,0.26,0.17,0.3,0.16,0.21,0.24,0.16,0.29,0.17,0.18,0.27,0.16,0.33,0.16,0.19,0.24,0.18,1.7,0.18,0.16,0.34,0.18,0.28,0.18,0.17,0.34,0.17,0.28,0.17,0.22,0.23,0.14,0.29,0.2,0.16,0.24,0.16,0.17,0.29,0.17,0.38,0.2,0.16,0.3,0.18,0.31,0.16,0.16,0.29,0.15,0.31,0.17,0.17,0.3,0.2,0.27,0.16,0.15,0.3,0.41,0.28,0.16,0.15,0.28,0.15,0.33,0.18,0.18,0.17,5.2,0.23,0.17,0.16,0.16,0.33,0.3,0.19,0.16,0.92,0.28,0.33,0.17,0.21,0.15,0.32,0.61,1.48,0.15,0.17,0.44,0.23,0.19,0.17,0.24,0.33,0.26,0.17,0.17,0.17,0.27,0.25,0.11,0.1,0.07,0.09,0.37,0.08,0.09,0.08,0.07,0.34,0.07,0.08,0.07,0.07,0.37,0.07,0.07,0.07,0.25,0.26,0.06,0.1,0.07,0.09,0.31,0.08,0.11,0.11,0.12,0.26,0.08,0.09,0.07,0.1,0.25,0.06,0.06,0.07,0.07,0.36,0.26,0.08,0.08,0.09,0.16,0.23,0.07,0.09,0.21,0.22,0.21,0.09,0.07,0.09,0.22,0.3,0.12,0.07,0.11],
				[14.02,14.01,14.01,14.01,14.01,14.03,14.03,14.02,14.02,14.03,14.03,14.04,14.03,14.03,14.03,14.02,14.04,14.03,14.03,14.03,14.03,14.03,14.03,14.03,14.03,14.03,14.04,14.04,14.03,14.03,14.03,14.04,14.03,14.04,14.04,14.04,14.05,14.03,14.03,14.03,14.04,14.04,14.05,14.03,14.03,14.03,14.03,14.05,14.04,14.04,14.04,14.03,14.04,14.03,14.04,14.04,14.03,14.04,14.03,14.03,14.03,14.03,14.02,14.02,14.02,14.01,14.01,14.02,14.02,14.02,14.02,14.02,14.02,14.01,14.01,14.02,14.02,14.02,14.03,14.02,14,14.02,14.02,14.04,14.03,14.02,14.02,14.02,14.03,14.02,14.03,14.03,14.03,14.03,14.02,14.02,14.02,14.02,14.02,14.02,14.02,14.02,14.02,14.03,14.03,14.02,14.02,14.02,14.02,14.36,14.08,14.08,14.08,14.08,14.04,14.03,14.03,14.03,14.03,14.03,14.03,14.03,14.03,14.03,14.03,14,14,14,14,14.03,14.03,14.03,14.03,14.03,14.03,14.03,14.03,14.03,14.04,14.04,14.03,14.01,14.01,14.01,14.01,14.03,14.01,14.01,14.01,14.01,14.04,14.03,14.04,14.04,14.04,14.02,14.01,14.01,14.01,14.03,14.04,14.03,14.03,14.03,14.04,14.04,14.03,14.03,14.03,14.04,14.05,14.04,14.03,14.03,14.03,14.03,14.04,14.04,14.04,14.03,14.03,14.04,14.03,14.04,14.04,14.04,14.04,14.03,14.03,14.04,14.04,14.05,14.04,14.04,14.04,14.02,14.05,14.04,14.03,14.03],
				[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0.01,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0.01,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0.01,0,0,0,0.01,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0.01,0,0,0,0,0.01,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0.01,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0.01,0,0,0.03],
			];

			data[1][35] = null;
			data[1][36] = null;
			data[1][37] = null;
			data[1][38] = null;
			data[1][39] = null;
			data[1][40] = null;

			data[2][79] = null;
			data[2][80] = null;
			data[2][91] = null;
			data[2][125] = null;
			data[2][126] = null;
			data[2][127] = null;

		//	data[2][197] = null;
		//	data[2][198] = null;
		//	data[2][199] = null;

			const opts = {
				title: "Missing Data (null values)",
				width: 1920,
				height: 600,
			/*
				hooks: {
					setLegend: [
						u => {
							if (u.legend.idx == null) {
								u.setLegend({idx: u.data[0].length - 1}, false);
							}
						},
					]
				},
			*/
				series: [
					{},
					{
						label: "CPU",
						scale: "%",
						value: (u, v, sidx, didx) => didx == null ? null : v == null ? "" : v.toFixed(1) + "%",
						stroke: "red",
						fill: "rgba(255,0,0,0.05)",
					//	spanGaps: true,
					},
					{
						label: "RAM",
						scale: "%",
						value: (u, v, sidx, didx) => didx == null ? null : v == null ? "" : v.toFixed(1) + "%",
						stroke: "blue",
						fill: "rgba(0,0,255,0.05)",
					//	spanGaps: true,
					},
					{
						label: "TCP Out",
						scale: "mb",
						value: (u, v, sidx, didx) => didx == null ? null : v == null ? "" : v.toFixed(1) + " MB",
						stroke: "green",
						fill: "rgba(0,255,0,0.05)",
					//	spanGaps: true,
					}
				],
				axes: [
					{},
					{
						scale: '%',
						values: (u, vals, space) => vals.map(v => +v.toFixed(1) + "%"),
					},
					{
						side: 1,
						scale: 'mb',
						values: (u, vals, space) => vals.map(v => +v.toFixed(2) + " MB"),
						grid: {show: false},
					},
				],
			};

			let u = new uPlot(opts, data, document.body);
		</script>
		<script>
			const isNum = Number.isFinite;
			const delta = 1;

			const opts3 = {
				title: "Insert gaps when adjacent points > delta",
				width: 1920,
				height: 600,
				scales: {
					x: {
						time: false,
					}
				},
				series: [
					{},
					{
						stroke: "red",
						// insert gaps where adjacent datapoints with values are > delta
						// todo: does not accumulate prior gap when adjacent so can make [1,2],[2,3] instead of [1,3]
						// todo: does not handle undefined-filled datasets (e.g. from unaligned joining)
						gaps: (u, sidx, idx0, idx1, nullGaps) => {
							let xData = u.data[0];
							let yData = u.data[sidx];

							let addlGaps = [];

							for (let i = idx0 + 1; i <= idx1; i++) {
								let xVal = xData[i];
								let yVal = yData[i];

								if (isNum(yData[i]) && isNum(yData[i-1])) {
									if (xData[i] - xData[i - 1] > delta) {
										uPlot.addGap(
											addlGaps,
											Math.round(u.valToPos(xData[i - 1], 'x', true)),
											Math.round(u.valToPos(xData[i],     'x', true)),
										);
									}
								}
							}

							nullGaps.push(...addlGaps);
							nullGaps.sort((a, b) => a[0] - b[0]);

							return nullGaps;
						}
					},
				]
			};

			const data3 = [
				[0, 1, 2, 3, 25, 26, 27, 28],
				[0, 1, 2, 3, 4, 5, 6, 7],
			];

			let u3 = new uPlot(opts3, data3, document.body);
		</script>
	</body>
</html>